<!DOCTYPE html>
<html lang="zh-cn">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JS015-轮播图案例</title>
</head>
<style>
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    body {
        background-color: #222;
    }

    .slide-box {
        margin: 1.5rem auto;
        width: 35rem;
        border-radius: .5rem;
        border: 2px solid gray;
        overflow: hidden;
    }

    .slide-head {
        position: relative;
        display: flex;
        height: 20rem;

        img.slide-image {
            object-fit: cover;
        }

        .slide-loading {
            position: absolute;
            inset: 0;
            display: flex;
            align-items: center;
            justify-content: center;
            color: dimgray;
            font-weight: bold;
            font-size: 2rem;
            background-color: lightgray;
            opacity: 0;
            transition: 200ms;
        }
    }

    .slide-foot {
        display: flex;
        flex-direction: column;
        justify-content: space-evenly;
        height: 6rem;
        padding: 0 1rem;
        background-color: gray;
        border-top: 2px solid gray;
        transition: 200ms;

        .head {
            display: flex;
            justify-content: space-between;
            align-items: center;

            h2.title {
                flex-grow: 1;
                color: #222;
            }

            span.btns {
                display: flex;
                justify-content: center;
                align-items: center;
                gap: .5rem;
            }

            span.btns button {
                width: 2.5rem;
                height: 2.25rem;
                background-color: #eee;
                font-weight: bold;
                font-size: 1.5rem;
                color: dimgray;
                border: 2px solid gray;
                border-radius: .5rem;
                cursor: pointer;
            }

            span.btns button:hover {
                color: #eee;
                background-color: gray;
            }
        }

        .foot {
            ul.nav-dots {
                display: flex;
                justify-content: start;
                align-items: start;
                gap: .5rem;

                li {
                    width: 1.25rem;
                    height: 1.25rem;
                    list-style: none;
                    cursor: pointer;
                    background-color: gray;
                    border: 2px solid dimgray;
                    border-radius: 50%;
                    transition: 200ms;
                }

                li.active {
                    background-color: #eee;
                }
            }
        }
    }

    .debug {
        width: 35rem;
        margin: 0 auto;
        padding: 1rem;
        border: 1px solid gray;
        color: snow;

        label {
            display: flex;
            align-items: center;
            gap: .25rem;

            input {
                height: 1.5rem;
                outline: none;
            }

            button {
                height: 1.5rem;
                padding: 0 .5rem;
            }
        }
    }
</style>

<body>
<div class="slide-box">
    <div class="slide-head">
        <img class="slide-image" src="" alt="轮播图"/>
        <div class="slide-loading">Loading...</div>
    </div>
    <div class="slide-foot">
        <div class="head">
            <h2 class="title">轮播图标题</h2>
            <span class="btns">
                  <button class="prev-btn">&lt;</button>
                  <button class="next-btn">&gt;</button>
                </span>
        </div>
        <div class="foot">
            <ul class="nav-dots">
                <li class="active"></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
            </ul>
        </div>
    </div>
</div>
<div class="debug">
    <label class="timeout">
        轮播周期：<input id="timeout" type="number" min="100" max="10000" value="5000">
        <button class="apply">应用</button>
    </label>
</div>
<script>
    const source = [
        {src: 'https://s2.loli.net/2025/09/23/2np3EkQMNBAjzZm.jpg', title: '重塑之手', color: 'lightblue',},
        {src: 'https://s2.loli.net/2025/09/23/LhHneoM2klxz6Kp.jpg', title: '海盗船长', color: 'lightpink',},
        {src: 'https://s2.loli.net/2025/09/23/crV72qjH4fyRLBe.jpg', title: '苏芙比', color: 'lightgreen',},
        {src: 'https://s2.loli.net/2025/09/23/feWuTx4mINCnLMF.jpg', title: '十四行诗', color: 'lightcoral',},
        {src: 'https://s2.loli.net/2025/09/23/WMR2lUq3xPh1mJZ.jpg', title: '槲寄生', color: 'lightsalmon',},
        {src: 'https://s2.loli.net/2025/09/23/4kfT7CR5rL8VUgh.jpg', title: '施奈德', color: 'lightyellow',},
    ]
    const slideBox = document.querySelector('.slide-box')
    const slideImage = document.querySelector('.slide-head .slide-image')
    const slideTitle = document.querySelector('.slide-foot .title')
    const slideFoot = document.querySelector('.slide-foot')
    const nextBtn = document.querySelector('.slide-foot .next-btn')
    const prevBtn = document.querySelector('.slide-foot .prev-btn')
    const navDots = document.querySelectorAll('.slide-foot ul.nav-dots li')
    const slideLoading = document.querySelector('.slide-loading')

    const debugTimeoutInput = document.querySelector('input#timeout')
    const debugTimeoutBtn = document.querySelector('.debug .timeout button.apply')
    let timeout = 5000

    // 图片索引信号量
    let curImageIndex = 0

    // 初始化
    updateSlideBox()

    function nextImageIndex() {
        curImageIndex = (curImageIndex + 1) % source.length
    }

    function prevImageIndex() {
        curImageIndex = (curImageIndex + source.length - 1) % source.length
    }

    // 设置事件监听
    nextBtn.addEventListener('click', function () {
        nextImageIndex()
        updateSlideBox()
    })

    prevBtn.addEventListener('click', function () {
        prevImageIndex()
        updateSlideBox()
    })

    for (let i = 0; i < navDots.length; i++) {
        const navDot = navDots[i]
        navDot.addEventListener('click', function () {
            curImageIndex = i
            updateSlideBox()
        })
    }

    slideImage.addEventListener('load', function () {
        //隐藏图片加载中
        slideLoading.style.opacity = '0'
    })

    debugTimeoutBtn.addEventListener('click', function () {
        timeout = debugTimeoutInput.value
        if (timeout < 100) timeout = 100
        else if (timeout > 10000) timeout = 10000
        debugTimeoutInput.value = timeout
        clearTimeout(autoMoveTimerId)
        initAutomotiveTimer()
    })

    // 更新界面
    function updateSlideBox() {
        const imgItem = source[curImageIndex]
        slideImage.src = imgItem.src
        slideTitle.innerText = imgItem.title
        slideFoot.style.backgroundColor = imgItem.color
        toggleNavDots()
        //显示图片加载中
        slideLoading.style.opacity = '1'
    }

    // 开关导航点
    function toggleNavDots() {
        const prevDot = document.querySelector('.slide-foot ul.nav-dots li.active')
        const currDot = document.querySelector(`.slide-foot ul.nav-dots li:nth-child(${curImageIndex + 1})`)
        prevDot.classList.remove('active')
        currDot.classList.add('active')
    }

    // 自动播放
    let autoMoveTimerId = -1

    function initAutomotiveTimer() {
        autoMoveTimerId = setInterval(function () {
            nextBtn.click()
        }, timeout)
    }

    initAutomotiveTimer()

    slideBox.addEventListener('mouseenter', function () {
        clearInterval(autoMoveTimerId)
    })

    slideBox.addEventListener('mouseleave', function () {
        clearInterval(autoMoveTimerId)
        initAutomotiveTimer()
    })

</script>
</body>

</html>